package com.yide.myworld.service.impl;

import cn.hutool.core.lang.UUID;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONWriter;
import com.google.gson.JsonObject;
import com.yide.myworld.constants.enums.EmptyEnum;
import com.yide.myworld.constants.enums.NeteaseMsgTypeEnum;
import com.yide.myworld.constants.enums.UserEnum;
import com.yide.myworld.domain.NeteaseAttachDto;
import com.yide.myworld.exception.ApiException;
import com.yide.myworld.utils.CheckSumUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * 网易云通信-三方
 *
 * @auth: byebyebye
 * @date: 2022/11/28 7:47 PM
 * @description:
 */
@Slf4j
@RefreshScope
public class NeteaseService {

    @Value("${netease.app.suffix:null}")
    private String suffix="djs";
    @Value("${netease.app.key:null}")
    private String appKey="6532e2b3d1349de5bf7429533d171480";
    @Value("${netease.app.secret:null}")
    private String appSecret="fab1e2f211d2";


    private String common(String url, List<NameValuePair> nvps) {
        String json;
        CloseableHttpClient httpClient = null;
        HttpPost httpPost = null;
        try {
            httpClient = HttpClients.createDefault();
            httpPost = new HttpPost(url);
            String nonce = new Random().nextInt(10000) + "";
            String curTime = String.valueOf((new Date()).getTime() / 1000L);
            //计算CheckSum
            String checkSum = CheckSumUtil.getCheckSum(appSecret, nonce, curTime);
            //设置请求的header
            httpPost.addHeader("AppKey", appKey);
            httpPost.addHeader("Nonce", nonce);
            httpPost.addHeader("CurTime", curTime);
            httpPost.addHeader("CheckSum", checkSum);
            httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
            //设置请求的参数
            httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
            HttpResponse response = httpClient.execute(httpPost);
            json = EntityUtils.toString(response.getEntity(), "utf-8");
            log.info("云信响应:[{}]", json);
            return json;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ApiException(e.getMessage());
        } finally {
            if (httpPost != null) {
                httpPost.releaseConnection();
            }
            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 创建网易云通信ID
     *
     * @param userId
     * @param nickname
     * @throws Exception
     */
    public String userCreate(String userId, String nickname) {
        String url = "https://api.netease.im/nimserver/user/create.action";
        //设置请求的参数
        List<NameValuePair> nvps = new ArrayList();
        nvps.add(new BasicNameValuePair("accid", suffix + userId)); //网易云通信ID
        nvps.add(new BasicNameValuePair("name", nickname));  //网易云通信ID昵称
        JsonObject json = new JsonObject();
        json.addProperty("vip", 0);
        json.addProperty("vipName", "");
        json.addProperty("vipIcoUrl", "");
        json.addProperty("vipIcoUrl2", "");
        json.addProperty("vipIsValid", "2"); //vip是否有效  1：有效  2：无效
        nvps.add(new BasicNameValuePair("props", json.toString()));
        //请求网易云服务端
        return common(url, nvps);
    }

    /**
     * 更新并获取新token
     *
     * @param userId
     * @return
     * @throws Exception
     */
    public String refreshToken(String userId) {
        String url = "https://api.netease.im/nimserver/user/refreshToken.action";
        //设置请求的参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("accid", suffix + userId)); //网易云通信ID
        //请求网易云服务端
        return common(url, nvps);
    }

    /**
     * 网易云创建聊天室
     *
     * @param userId       用户id
     * @param chatRoomName 聊天室名称
     * @param announcement 公告
     * @param broadcasturl 直播地址
     * @param ext          扩展字段
     */
    public String chatRoomCreate(String userId, String chatRoomName, String announcement,
                                 String broadcasturl, String ext) {
        String url = "https://api.netease.im/nimserver/chatroom/create.action";
        //设置请求的参数
        List<NameValuePair> nvps = new ArrayList<>();
        nvps.add(new BasicNameValuePair("creator", suffix + userId));
        nvps.add(new BasicNameValuePair("name", chatRoomName));
        nvps.add(new BasicNameValuePair("announcement", announcement));
        nvps.add(new BasicNameValuePair("broadcasturl", broadcasturl));
        nvps.add(new BasicNameValuePair("ext", ext));
        //请求网易云服务端
        return common(url, nvps);
    }

    /**
     * 查询聊天室信息 返回在线人数
     *
     * @param roomId 聊天室Id
     */
    public String chatRoomGet(String roomId) {
        String url = "https://api.netease.im/nimserver/chatroom/get.action";
        //设置请求的参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("roomid", roomId + ""));               //聊天室id
        nvps.add(new BasicNameValuePair("needOnlineUserCount", "true"));  //是否需要返回在线人数，true或false，默认false
        //请求网易云服务端
        return common(url, nvps);
    }


    /**
     * 更新用户名片
     *
     * @param userId
     * @param nickName
     * @param profilePath
     * @param info
     * @param sex
     * @return
     */
    public String updateUserInfo(String userId, String nickName, String profilePath, String info, String sex, String chatRoomId, String roomTitle, String roomIcon, String onlineState) {
        String url = "https://api.netease.im/nimserver/user/updateUinfo.action";
        //设置请求的参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        //网易云通信ID
        nvps.add(new BasicNameValuePair("accid", suffix + userId));
        //用户昵称，最大长度64字符
        nvps.add(new BasicNameValuePair("name", nickName));
        //用户icon，最大长度1024字符
        nvps.add(new BasicNameValuePair("icon", profilePath));
        //用户签名，最大长度256字符
        nvps.add(new BasicNameValuePair("sign", info));
        //用户性别，0表示未知，1表示男，2女表示女
//        String sex = ssUser.getSex();
        int gender = 0;
        if (UserEnum.FEMALE.getCode().equals(sex)) {
            gender = 2;
        } else if (UserEnum.MALE.getCode().equals(sex)) {
            gender = 1;
        }

        //用户性别，0表示未知，1表示男，2女表示女，其它会报参数错误
        nvps.add(new BasicNameValuePair("gender", gender + ""));

        JsonObject json = new JsonObject();
        if (StringUtils.isNotBlank(chatRoomId)) {
            json.addProperty("chatRoomId", chatRoomId);
        }
        if (StringUtils.isNotBlank(chatRoomId)) {
            json.addProperty("roomTitle", roomTitle);
        }
        if (StringUtils.isNotBlank(chatRoomId)) {
            json.addProperty("roomIcon", roomIcon);
        }
        if (StringUtils.isNotBlank(onlineState)) {
            json.addProperty("onlineState", onlineState);
        }
        //001代表清空房间id
        if (StringUtils.isNotBlank(chatRoomId) && EmptyEnum.EMPTY_ROOM_ID.getCode().equals(chatRoomId)) {
            chatRoomId = "";
            json.addProperty("chatRoomId", chatRoomId);
        }
        //002清空房间名
        if (StringUtils.isNotBlank(roomTitle) && EmptyEnum.EMPTY_ROOM_TITLE.getCode().equals(roomTitle)) {
            roomTitle = "";
            json.addProperty("roomTitle", roomTitle);
        }
        //003 清空房间图标
        if (StringUtils.isNotBlank(roomIcon) && EmptyEnum.EMPTY_ROOM_ICON.getCode().equals(roomIcon)) {
            roomIcon = "";
            json.addProperty("roomIcon", roomIcon);
        }

//        //魅力等级相关字段
//        if (charmConfig != null) {
//            json.addProperty("charmConfigId", charmConfig.getId());
////            json.addProperty("charmConfigName", charmConfig.getCharmName());
//            json.addProperty("charmTxtIconUrl", charmConfig.getCharmTxtIconUrl());
//            json.addProperty("charmIconUrl", charmConfig.getCharmIconUrl());
//            json.addProperty("charmLevel", charmConfig.getId());
//        }
//        //用户名片扩展字段，最大长度1024字符，用户可自行扩展，建议封装成JSON字符串
        nvps.add(new BasicNameValuePair("ex", json.toString()));


        return common(url, nvps);
    }

    /**
     * 更新用户名片，不涉及房间相关信息
     *
     * @param userId
     * @param nickName
     * @param profilePath
     * @param info
     * @param sex
     * @return
     */
    public String updateUserInfoWithoutChatRoom(String userId, String nickName, String profilePath, String info, String sex) {
        String url = "https://api.netease.im/nimserver/user/updateUinfo.action";
        //设置请求的参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        //网易云通信ID
        nvps.add(new BasicNameValuePair("accid", suffix + userId));
        //用户昵称，最大长度64字符
        nvps.add(new BasicNameValuePair("name", nickName));
        //用户icon，最大长度1024字符
        nvps.add(new BasicNameValuePair("icon", profilePath));
        //用户签名，最大长度256字符
        nvps.add(new BasicNameValuePair("sign", info));
        //用户性别，0表示未知，1表示男，2女表示女
//        String sex = ssUser.getSex();
        int gender = 0;
        if (UserEnum.FEMALE.getCode().equals(sex)) {
            gender = 2;
        } else if (UserEnum.MALE.getCode().equals(sex)) {
            gender = 1;
        }
        //用户性别，0表示未知，1表示男，2女表示女，其它会报参数错误
        nvps.add(new BasicNameValuePair("gender", gender + ""));
        return common(url, nvps);
    }

    /**
     * 聊天室系统消息推送
     *
     * @param neteaseChatId 聊天室id
     * @param userId        用户通行证Id
     * @param msgType       消息类型
     *                      0: 表示文本消息，
     *                      1: 表示图片，
     *                      2: 表示语音，
     *                      3: 表示视频，
     *                      4: 表示地理位置信息，
     *                      6: 表示文件，
     *                      10: 表示Tips消息，
     *                      100: 自定义消息类型
     * @param attach        消息内容(JSON格式，长度限制4096字符)
     * @param ext           消息扩展字段(JSON格式，长度限制4096字符)
     *                      highPriority        消息的优先级 重要的true
     * @return
     * @throws Exception
     */
    public String roomMessagePush(String neteaseChatId, String userId, NeteaseMsgTypeEnum msgType, NeteaseAttachDto<?> attach, String ext, Boolean highPriority) {
        String url = "https://api.netease.im/nimserver/chatroom/sendMsg.action";
        //生成客户端消息ID
        UUID uuid = UUID.randomUUID();
        String msgIduuId = uuid.toString();
        String msgId = msgIduuId + userId;
        //设置请求的参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();

        nvps.add(new BasicNameValuePair("roomid", neteaseChatId));
        nvps.add(new BasicNameValuePair("msgId", msgId));
        nvps.add(new BasicNameValuePair("fromAccid", suffix + userId));
        nvps.add(new BasicNameValuePair("msgType", msgType.getCode()));
        nvps.add(new BasicNameValuePair("attach", JSON.toJSONString(attach, JSONWriter.Feature.WriteMapNullValue)));
        nvps.add(new BasicNameValuePair("ext", ext));
        nvps.add(new BasicNameValuePair("highPriority", highPriority.toString()));
        nvps.add(new BasicNameValuePair("needHighPriorityMsgResend", "false"));
        //请求网易云服务端
        return common(url, nvps);
    }

    /**
     * 聊天室广播消息推送(请使用系统守护房间消息发送的方式发送广播)
     *
     * @param userId  发消息用户id
     * @param msgType 消息类型
     *                0: 表示文本消息，
     *                1: 表示图片，
     *                2: 表示语音，
     *                3: 表示视频，
     *                4: 表示地理位置信息，
     *                6: 表示文件，
     *                10: 表示Tips消息，
     *                100: 自定义消息类型
     * @param attach  附件消息内容(JSON格式，长度限制4096字符)
     * @param ext     消息扩展字段(JSON格式，长度限制4096字符)
     *                highPriority        消息的优先级 重要的true
     * @return
     * @throws Exception
     */
    @Deprecated
    public String chatroomBroadcastMessagePush(String userId, NeteaseMsgTypeEnum msgType, NeteaseAttachDto<?> attach, String ext, Boolean highPriority) {
        String url = "https://api.netease.im/nimserver/chatroom/broadcast.action";
        //生成客户端消息ID
        UUID uuid = UUID.randomUUID();
        String msgIduuId = uuid.toString();
        String msgId = msgIduuId + userId;
        //设置请求的参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();

        nvps.add(new BasicNameValuePair("msgId", msgId));
        nvps.add(new BasicNameValuePair("fromAccid", suffix + userId));
        nvps.add(new BasicNameValuePair("msgType", msgType.getCode()));
        nvps.add(new BasicNameValuePair("attach", JSON.toJSONString(attach, JSONWriter.Feature.WriteMapNullValue)));
        nvps.add(new BasicNameValuePair("ext", ext));
        nvps.add(new BasicNameValuePair("highPriority", highPriority.toString()));
        log.info("发送房间广播消息,附件内容为：{}", JSON.toJSONString(attach, JSONWriter.Feature.WriteMapNullValue));
        //请求网易云服务端
        return common(url, nvps);
    }

    /**
     * 点对点发送消息
     * 参考文档：
     * https://doc.yunxin.163.com/messaging/docs/DQ2NTg4ODE?platform=server
     *
     * @param sourceUserId 发送人用户id
     * @param targetUserId 接收人用户id
     * @param msgType      消息类型
     *                     100: 自定义消息类型
     * @param body         消息内容(JSON格式)
     * @param ext          消息扩展字段(JSON格式，长度限制4096字符)
     * @return
     */
    public String pointToPointSendMsg(String sourceUserId, String targetUserId, NeteaseMsgTypeEnum msgType, Object body, String ext) {
        String url = "https://api.netease.im/nimserver/msg/sendMsg.action";
        //设置请求的参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();

        nvps.add(new BasicNameValuePair("from", suffix + sourceUserId));
        //仅可传入 0 或 1，0：单聊消息，1：群消息（高级群）
        nvps.add(new BasicNameValuePair("ope", "0"));
        nvps.add(new BasicNameValuePair("to", suffix + targetUserId));
        nvps.add(new BasicNameValuePair("type", msgType.getCode()));
        nvps.add(new BasicNameValuePair("body", JSON.toJSONString(body, JSONWriter.Feature.WriteMapNullValue)));
        nvps.add(new BasicNameValuePair("ext", ext));
        //请求网易云服务端
        return common(url, nvps);
    }


    /**
     * 设置（取消）管理员
     *
     * @param neteaseChatId 聊天室Id
     * @param operator      操作者账号accid
     * @param target        被操作者账号accid
     * @param opt           操作：
     *                      1: 设置为管理员，operator必须是创建者
     *                      2:设置普通等级用户，operator必须是创建者或管理员
     *                      -1:设为黑名单用户，operator必须是创建者或管理员
     *                      -2:设为禁言用户，operator必须是创建者或管理员
     * @param optvalue      true或false，true:设置；false:取消设置
     * @param notifyExt     通知扩展字段，长度限制2048，请使用json格式(可不传)
     */
    public String setMemberRole(String neteaseChatId, String operator, String target, String opt, String optvalue, String notifyExt) {
        String url = "https://api.netease.im/nimserver/chatroom/setMemberRole.action";
        //设置请求的参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("roomid", neteaseChatId + ""));
        nvps.add(new BasicNameValuePair("operator", suffix + operator));
        nvps.add(new BasicNameValuePair("target", suffix + target));
        nvps.add(new BasicNameValuePair("opt", opt));
        nvps.add(new BasicNameValuePair("optvalue", optvalue));
        nvps.add(new BasicNameValuePair("notifyExt", notifyExt));
        //请求网易云服务端
        return common(url, nvps);
    }


    /**
     * 设置临时禁言状态
     *
     * @param neteaseChatId 聊天室id
     * @param operator      操作者accid,必须是管理员或创建者
     * @param target        被禁言的目标账号accid
     * @param muteDuration  0:解除禁言;>0设置禁言的秒数，不能超过2592000秒(30天)
     * @param needNotify    操作完成后是否发送通知消息，true：发送，false：不发送，默认 true
     * @param notifyExt     通知消息的扩展字段，长度限制 2048 字符
     * @return
     */
    public String temporaryMute(String neteaseChatId, String operator, String target, Long muteDuration, Boolean needNotify, String notifyExt) {
        String url = "https://api.netease.im/nimserver/chatroom/temporaryMute.action";
        //设置请求的参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("roomid", neteaseChatId));
        nvps.add(new BasicNameValuePair("operator", suffix + operator));
        nvps.add(new BasicNameValuePair("target", suffix + target));
        nvps.add(new BasicNameValuePair("muteDuration", muteDuration + ""));
        nvps.add(new BasicNameValuePair("needNotify", needNotify.toString()));
        nvps.add(new BasicNameValuePair("notifyExt", notifyExt));
        //请求网易云服务端
        return common(url, nvps);
    }


    /**
     * 设置黑名单
     *
     * @param accid        用户账号accid
     * @param targetAcc    被拉黑或被静音的账号accid
     * @param relationType 本次操作的类型 1 黑名单操作（拉黑）；2 设置静音操作
     * @param value        操作值 0 取消拉黑或静音；1 加入黑名单或静音
     * @return
     */
    public String setSpecialRelation(String accid, String targetAcc, String relationType, String value) {
        String url = "https://api.netease.im/nimserver/user/setSpecialRelation.action";
        //设置请求的参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("accid", suffix + accid));
        nvps.add(new BasicNameValuePair("targetAcc", suffix + targetAcc));
        nvps.add(new BasicNameValuePair("relationType", relationType));
        nvps.add(new BasicNameValuePair("value", value));
        //请求网易云服务端
        return common(url, nvps);
    }


    /**
     * 自定义系统通知(默认是离线消息，后续该方法会废弃)
     *
     * @param userId       发送者accid，用户帐号，最大32字符，APP内唯一
     * @param msgtype      0：点对点自定义通知，1：群消息自定义通知，其他返回414
     * @param targetUserId msgtype=0 时需填入接收系统通知的用户的的云信 IM 账号（accid），msgtype=1 时需填入接收系统通知的群的 ID（即 tid），最大 32 字符
     * @param attach       自定义系统通知的具体内容，开发者组装的字符串，建议 JSON 格式，最大长度 4096 字符
     * @return
     */
    @Deprecated
    public String sendAttachMsg(String userId, String msgtype, String targetUserId, String attach) {
        String url = "https://api.netease.im/nimserver/msg/sendAttachMsg.action";
        //设置请求的参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("from", suffix + userId));
        nvps.add(new BasicNameValuePair("msgtype", msgtype));
        nvps.add(new BasicNameValuePair("to", suffix + targetUserId));
        nvps.add(new BasicNameValuePair("attach", attach));
        //请求网易云服务端
        return common(url, nvps);
    }


    /**
     * 自定义系统通知（可选在线还是离线）
     *
     * @param userId       发送者accid，用户帐号，最大32字符，APP内唯一
     * @param msgtype      0：点对点自定义通知，1：群消息自定义通知，其他返回414
     * @param targetUserId msgtype=0 时需填入接收系统通知的用户的的云信 IM 账号（accid），msgtype=1 时需填入接收系统通知的群的 ID（即 tid），最大 32 字符
     * @param attach       自定义系统通知的具体内容，开发者组装的字符串，建议 JSON 格式，最大长度 4096 字符
     * @param save         离线消息标识（1表示在线，2表示离线。默认2）
     * @return
     */
    public String sendAttachMsg(String userId, String msgtype, String targetUserId, String attach, String save) {
        String url = "https://api.netease.im/nimserver/msg/sendAttachMsg.action";
        //设置请求的参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("from", suffix + userId));
        nvps.add(new BasicNameValuePair("msgtype", msgtype));
        nvps.add(new BasicNameValuePair("to", suffix + targetUserId));
        nvps.add(new BasicNameValuePair("attach", attach));
        nvps.add(new BasicNameValuePair("save", save));
        //请求网易云服务端
        return common(url, nvps);
    }

    /**
     * 用户广播消息
     *
     * @param userId   发送人的id
     * @param body     消息体 json格式
     * @param targetOs 目标客户端：默认所有客户端，JSONArray，格式：["ios","aos","pc","web","mac"]
     * @return
     */
    public String msgBroadcastMessagePush(String userId, NeteaseAttachDto<?> body, List<String> targetOs) {
        String url = "https://api.netease.im/nimserver/msg/broadcastMsg.action";
        //设置请求的参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("body", JSON.toJSONString(body, JSONWriter.Feature.WriteMapNullValue)));
        nvps.add(new BasicNameValuePair("from", suffix + userId));//发送人accid
        nvps.add(new BasicNameValuePair("isOffline", "true"));//广播消息是否离线
        log.info("发送平台广播消息,附件内容为：{}", JSON.toJSONString(body, JSONWriter.Feature.WriteMapNullValue));
        //请求网易云服务端
        return common(url, nvps);
    }

    /**
     * 创建系统管理员用户(保留切勿删除，切换云信账号时使用)
     */
    @Deprecated
    private static void createSystemUser() {
        NeteaseService service = new NeteaseService();
        String response = service.userCreate("Administrator", "系统管理员");
        System.out.println("创建系统管理员消息");
        System.out.println(response);
    }

    /**
     * 创建系统后台守护房间(保留切勿删除，切换云信账号时使用)
     */
    @Deprecated
    private static void createDaemonNeteaseRoom() {
        NeteaseService service = new NeteaseService();
        String response = service.chatRoomCreate("Administrator", "系统守护房间", "", "", "");
        System.out.println("创建守护房间消息");
        System.out.println(response);
    }

    public static void main(String[] args) {
        createSystemUser();
        createDaemonNeteaseRoom();

    }
}
